#include "Terrain.h"
#include <stdlib.h>
#include <stdio.h>
#include <cassert>


/* Procédure qui va permettre l'initialisation de la structure terrain.
 * Elle prend en paramètres un pointeur sur une structure Terrain.
 * Cette procédure va en fait remplir (selon un fichier stocké
 * séparément que l'on a appelé Terrain.txt) le tableau d'entiers ainsi
 * que les valeurs de longueur et de hauteur correspondant au terrain
 * de jeu */
void init_terrain (Sterrain* ter)
{
/* Création des compteurs de ligne(i), de colonnes(j) et d'un compteur qui va stocker 
 * la valeur max de j afin de pouvoir connaitre la taille du terrain) */
	int i;
	int j;
	int k;
/* Mise à zero des compteurs (inutile pour j car il faudra de toute facon le faire dans
 * la boucle*/
	i=0;
	k=0;

/* Déclaration d'un caractère qui va nous permettre de stocker la valeur lue dans le
 * fichier et d'un pointeur sur fichier qui va permettre d'aller ouvrir le fichier
 * contenant le terrain */
	char caractereActuel;
	FILE* fichier=NULL;
/* Ouverture du fichier et vérification grace au assert que tout s'est bien passé */
	fichier = fopen("Terrain.txt", "r");
	assert (fichier!=NULL);

/* Boucle de recopie du fichier dans la structure : tant qu'on arrive pas à la fin du
 * fichier (=EOF), on continue */
	do
	{
/* On va ici rentrer dans la boucle qui recopie les lignes il faut donc penser à 
 * remettre à chaque nouvelle ligne le compteur de colonnes à zero !*/
		j=0;
		do
		{
/* On lit le caractère suivant et on le stocke dans la variable prévue à cet effet */
			caractereActuel = fgetc(fichier);
/* Cette condition semble assez étrange... C'est parce qu'il y a des caractères spéciaux
 * en début de fichier qu'on ne veut pas recopier dans notre structure, heureusement pour
 * nous, ils sont négatifs (et donc si ce test est faux, on ne veut surtout rien changer
 * et paser à la lecture du caractère suivant) */
			if (caractereActuel>=0)
			{
/* On vérifie qu'il ne s'agisse pas d'un caractère spécial (fin de ligne ou fin de fichier)
 * et si ce n'est pas le cas on le recopie en oubliant pas de retrancher 48 afin de
 * convertir le code ASCII de 0 en l'entier 0 */
				if ((caractereActuel != '\n') and (caractereActuel != EOF))
				{
					(*ter).terrain[i][j]=caractereActuel-48;
				}
/* On incrémente le compteur de colonne afin d'avancer dans le tableau représentant le
 * terrain */
				j++;
/* ici, on cherche à stocker dans k la valeur maximale de j afin de connaitre le nombre
 * de colonnes de notre tableau */
				if (k<j)
				{
					k=j;
				}
			}
		}
		while ((caractereActuel != '\n') and (caractereActuel != EOF));
/* Si on est à un caractère de fin de ligne, on incrémente notre compteur de ligne */
		i++;
		}
	while (caractereActuel != EOF);
/* Une fois qu'on a fini de recopier le tableau, il faut remplir les champs longueur et
 * hauteur de notre structure */
	(*ter).longueur=(k-1);
	(*ter).hauteur=(i-1);
/* On n'oublie pas de fermer le fichier... */
	fclose(fichier);
}
	
/* Cette fonction est un accesseur à une case du terrain :
 * AUCUN DE SES PARAMETRES NE POURRA ETRE MODIFIE APRES SON EXECUTION.
 * Elle prend en paramètres un X (abscisse) et un Y (ordonnée)
 * correspondant à une case du terrain ainsi qu'un pointeur sur une
 * structure terrain.
 * Elle renvoie un entier qui sera en fait égal soit à 0 (case libre), soit à 1 (chemin)
 * soit à 2 (tour) */
int get_terrain (const int X, const int Y, const Sterrain* ter)
{
/* Tout d'abord, on commence par vérifier qu'on n'essaye pas d'acceder à une case qui est
 * en dehors du terrain de jeu ! */
	assert (X>=0);
	assert (X<=(*ter).longueur);
	assert (Y>=0);
	assert (Y<=(*ter).hauteur);
/* Si tout va bien on renvoie alors le contenu de la case en question */
	return ((*ter).terrain[Y][X]);
}

/* Cette fonction est un accesseur à la longueur du terrain :
 * AUCUN DE SES PARAMETRES NE POURRA ETRE MODIFIE APRES SON EXECUTION.
 * Elle prend en paramètre un pointeur sur une structure terrain.
 * Elle renvoie un entier correspondant à la longueur en nombre de cases du terrain */
int get_longueur (const Sterrain* ter)
{
	return ((*ter).longueur);
}

/* Cette fonction est un accesseur à la hauteur du terrain :
 * AUCUN DE SES PARAMETRES NE POURRA ETRE MODIFIE APRES SON EXECUTION.
 * Elle prend en paramètre un pointeur sur une structure terrain.
 * Elle renvoie un entier correspondant à la hauteur en nombre de cases du terrain */
int get_hauteur (const Sterrain* ter)
{
	return ((*ter).hauteur);
}

/* Cette procédure est un mutateur des cases du terrain de jeu.
 * ATTENTION, APRES SON EXECUTION, LE TERRAIN SERA MODIFIE !
 * Elle prend en paramètres un X (abscisse) et un Y (ordonnée)
 * correspondant à une case du terrain ainsi qu'un pointeur sur une
 * structure terrain et une valeur qui devra être égale à 0 (case libre),
 * 1 (chemin) ou 2, 3, 4, ou 5 (tours).*/
void set_terrain (int X, int Y, Sterrain* ter, int valeur)
{
/* On commence par vérifier qu'on essaye pas de modifier un emplacement extrerieur
 * au terrain de jeu */
	assert (X>=0);
	assert (X<=(*ter).longueur);
	assert (Y>=0);
	assert (Y<=(*ter).hauteur);
/* On vérifie également que la valeur passée en paramètre correspond bien à une valeur*
 * significative */
	assert (0 <= valeur);
	assert (valeur <= 5);
/* On modifie ensuite la case du terrain concernée */
	(*ter).terrain[Y][X]=valeur;
}

	
